namespace SubhadraSolutions.Sharp.Logging.Adapters.Log4Net
{
    using log4net;
    using log4net.Util;
    using SubhadraSolutions.Sharp.Logging.Contracts;
    using System;
    using System.Globalization;

    public sealed class LoggerAsLogAdapter : ILog
    {
        #region Fields

        private readonly ILogger _adaptee;

        #endregion Fields

        #region Constructors

        public LoggerAsLogAdapter(ILogger adaptee)
        {
            _adaptee = adaptee;
        }

        #endregion Constructors

        #region Properties

        public bool IsDebugEnabled
        {
            get { return true; }
        }

        public bool IsErrorEnabled
        {
            get { return true; }
        }

        public bool IsFatalEnabled
        {
            get { return true; }
        }

        public bool IsInfoEnabled
        {
            get { return true; }
        }

        public bool IsWarnEnabled
        {
            get { return true; }
        }

        //
        public log4net.Core.ILogger Logger
        {
            get;
            set;
        }

        #endregion Properties

        #region Methods

        public void Debug(object message, Exception exception)
        {
            _adaptee.Log(LogItemSeverity.DEBUG, LogItemCategories.Technical, message == null ? null : message.ToString(), exception);
        }

        public void Debug(object message)
        {
            _adaptee.Log(LogItemSeverity.DEBUG, LogItemCategories.Technical, message == null ? null : message.ToString(), null);
        }

        public void DebugFormat(IFormatProvider provider, string format, params object[] args)
        {
            var f = new SystemStringFormat(provider, format, args);
            _adaptee.Log(LogItemSeverity.DEBUG, LogItemCategories.Technical, f.ToString(), null);
        }

        public void DebugFormat(string format, object arg0, object arg1, object arg2)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format,
                new[] { arg0, arg1, arg2 });
            _adaptee.Log(LogItemSeverity.DEBUG, LogItemCategories.Technical, f.ToString(), null);
        }

        public void DebugFormat(string format, object arg0, object arg1)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0, arg1 });
            _adaptee.Log(LogItemSeverity.DEBUG, LogItemCategories.Technical, f.ToString(), null);
        }

        public void DebugFormat(string format, object arg0)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0 });
            _adaptee.Log(LogItemSeverity.DEBUG, LogItemCategories.Technical, f.ToString(), null);
        }

        public void DebugFormat(string format, params object[] args)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, args);
            _adaptee.Log(LogItemSeverity.DEBUG, LogItemCategories.Technical, f.ToString(), null);
        }

        //
        public void Error(object message, Exception exception)
        {
            _adaptee.Log(LogItemSeverity.ERROR, LogItemCategories.Technical, message == null ? null : message.ToString(), exception);
        }

        public void Error(object message)
        {
            _adaptee.Log(LogItemSeverity.ERROR, LogItemCategories.Technical, message == null ? null : message.ToString(), null);
        }

        public void ErrorFormat(IFormatProvider provider, string format, params object[] args)
        {
            var f = new SystemStringFormat(provider, format, args);
            _adaptee.Log(LogItemSeverity.ERROR, LogItemCategories.Technical, f.ToString(), null);
        }

        public void ErrorFormat(string format, object arg0, object arg1, object arg2)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format,
                new[] { arg0, arg1, arg2 });
            _adaptee.Log(LogItemSeverity.ERROR, LogItemCategories.Technical, f.ToString(), null);
        }

        public void ErrorFormat(string format, object arg0, object arg1)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0, arg1 });
            _adaptee.Log(LogItemSeverity.ERROR, LogItemCategories.Technical, f.ToString(), null);
        }

        public void ErrorFormat(string format, object arg0)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0 });
            _adaptee.Log(LogItemSeverity.ERROR, LogItemCategories.Technical, f.ToString(), null);
        }

        public void ErrorFormat(string format, params object[] args)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, args);
            _adaptee.Log(LogItemSeverity.ERROR, LogItemCategories.Technical, f.ToString(), null);
        }

        //
        public void Fatal(object message, Exception exception)
        {
            _adaptee.Log(LogItemSeverity.FATAL, LogItemCategories.Technical, message == null ? null : message.ToString(), exception);
        }

        public void Fatal(object message)
        {
            _adaptee.Log(LogItemSeverity.FATAL, LogItemCategories.Technical, message == null ? null : message.ToString(), null);
        }

        public void FatalFormat(IFormatProvider provider, string format, params object[] args)
        {
            var f = new SystemStringFormat(provider, format, args);
            _adaptee.Log(LogItemSeverity.FATAL, LogItemCategories.Technical, f.ToString(), null);
        }

        public void FatalFormat(string format, object arg0, object arg1, object arg2)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format,
                new[] { arg0, arg1, arg2 });
            _adaptee.Log(LogItemSeverity.FATAL, LogItemCategories.Technical, f.ToString(), null);
        }

        public void FatalFormat(string format, object arg0, object arg1)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0, arg1 });
            _adaptee.Log(LogItemSeverity.FATAL, LogItemCategories.Technical, f.ToString(), null);
        }

        public void FatalFormat(string format, object arg0)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0 });
            _adaptee.Log(LogItemSeverity.FATAL, LogItemCategories.Technical, f.ToString(), null);
        }

        public void FatalFormat(string format, params object[] args)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, args);
            _adaptee.Log(LogItemSeverity.FATAL, LogItemCategories.Technical, f.ToString(), null);
        }

        //
        public void Info(object message, Exception exception)
        {
            _adaptee.Log(LogItemSeverity.INFO, LogItemCategories.Technical, message == null ? null : message.ToString(), exception);
        }

        public void Info(object message)
        {
            _adaptee.Log(LogItemSeverity.INFO, LogItemCategories.Technical, message == null ? null : message.ToString(), null);
        }

        public void InfoFormat(IFormatProvider provider, string format, params object[] args)
        {
            var f = new SystemStringFormat(provider, format, args);
            _adaptee.Log(LogItemSeverity.INFO, LogItemCategories.Technical, f.ToString(), null);
        }

        public void InfoFormat(string format, object arg0, object arg1, object arg2)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format,
                new[] { arg0, arg1, arg2 });
            _adaptee.Log(LogItemSeverity.INFO, LogItemCategories.Technical, f.ToString(), null);
        }

        public void InfoFormat(string format, object arg0, object arg1)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0, arg1 });
            _adaptee.Log(LogItemSeverity.INFO, LogItemCategories.Technical, f.ToString(), null);
        }

        public void InfoFormat(string format, object arg0)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0 });
            _adaptee.Log(LogItemSeverity.INFO, LogItemCategories.Technical, f.ToString(), null);
        }

        public void InfoFormat(string format, params object[] args)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, args);
            _adaptee.Log(LogItemSeverity.INFO, LogItemCategories.Technical, f.ToString(), null);
        }

        //
        public void Warn(object message, Exception exception)
        {
            _adaptee.Log(LogItemSeverity.WARN, LogItemCategories.Technical, message == null ? null : message.ToString(), exception);
        }

        public void Warn(object message)
        {
            _adaptee.Log(LogItemSeverity.WARN, LogItemCategories.Technical, message == null ? null : message.ToString(), null);
        }

        public void WarnFormat(IFormatProvider provider, string format, params object[] args)
        {
            var f = new SystemStringFormat(provider, format, args);
            _adaptee.Log(LogItemSeverity.WARN, LogItemCategories.Technical, f.ToString(), null);
        }

        public void WarnFormat(string format, object arg0, object arg1, object arg2)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format,
                new[] { arg0, arg1, arg2 });
            _adaptee.Log(LogItemSeverity.WARN, LogItemCategories.Technical, f.ToString(), null);
        }

        public void WarnFormat(string format, object arg0, object arg1)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0, arg1 });
            _adaptee.Log(LogItemSeverity.WARN, LogItemCategories.Technical, f.ToString(), null);
        }

        public void WarnFormat(string format, object arg0)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, new[] { arg0 });
            _adaptee.Log(LogItemSeverity.WARN, LogItemCategories.Technical, f.ToString(), null);
        }

        public void WarnFormat(string format, params object[] args)
        {
            var f = new SystemStringFormat(CultureInfo.InvariantCulture, format, args);
            _adaptee.Log(LogItemSeverity.WARN, LogItemCategories.Technical, f.ToString(), null);
        }

        #endregion Methods
    }
}